package pl.kosmowska.ewelina.client.views.impl;

import java.util.Iterator;
import java.util.List;

import pl.kosmowska.ewelina.client.app.requestfactory.dto.CategoryDataProxy;
import pl.kosmowska.ewelina.client.app.requestfactory.dto.CategoryItemDataProxy;
import pl.kosmowska.ewelina.client.views.CategoryView;
import pl.kosmowska.ewelina.client.views.widgets.CategoryEditItemWidget;
import pl.kosmowska.ewelina.client.views.widgets.CategoryWidget;
import pl.kosmowska.ewelina.client.views.widgets.MessageDialogBox;
import pl.kosmowska.ewelina.client.views.widgets.events.ItemAddedEvent;
import pl.kosmowska.ewelina.client.views.widgets.events.ItemAddedHandler;
import pl.kosmowska.ewelina.client.views.widgets.events.ItemEditedEvent;
import pl.kosmowska.ewelina.client.views.widgets.events.ItemEditedHandler;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class CategoryViewImpl extends Composite  implements CategoryView{

	@UiField VerticalPanel leftCategoryPanel;
	@UiField Button categoryAddButton;
	private boolean alreadyInit;
	private Presenter presenter;
	private List<CategoryDataProxy> categoryDataList;
	Tree categoryTree = new Tree();
	TreeItem categoryRoot;


	private static CategoryViewImplUiBinder uiBinder = GWT
			.create(CategoryViewImplUiBinder.class);

	interface CategoryViewImplUiBinder extends
	UiBinder<Widget, CategoryViewImpl> {
	}

	public CategoryViewImpl() {
		initWidget(uiBinder.createAndBindUi(this));

	}


	@Override
	public void setPresenter(Presenter presenter) {
		this.presenter = presenter;
	}


	private void drawTree() {
		leftCategoryPanel.clear();
		if (categoryDataList == null || 
				categoryDataList.size() == 0) {

		}else{
			Iterator<CategoryDataProxy> itr = categoryDataList.iterator();
			while(itr.hasNext()) {
				CategoryDataProxy categoryData = itr.next();
				createAndAttachCategory(categoryData);
			}
		}
		categoryRoot.setState(true);
		leftCategoryPanel.add(categoryTree);
	}


	private TreeItem createAndAttachCategory(CategoryDataProxy categoryData) {
		CategoryWidget mainCategoryWidget= getMainCategoryItem(categoryData);
		TreeItem mailPanelRoot = categoryRoot.addItem(mainCategoryWidget);
		mainCategoryWidget.setTreeItem(mailPanelRoot);
		atachHandler(mainCategoryWidget, mailPanelRoot);
		mainCategoryWidget.draw();

		if(categoryData!=null){
			int i=0;
			Iterator<CategoryItemDataProxy> itr = categoryData.getItems().iterator();
			while(itr.hasNext()) {
				CategoryItemDataProxy categoryItem = itr.next();
				attachToTree(mailPanelRoot, categoryItem, i, mainCategoryWidget);
				i++;
			}
		}
		return mailPanelRoot;
	}	

	private CategoryWidget getMainCategoryItem(
			CategoryDataProxy categoryData) {
		CategoryWidget wItem = new CategoryWidget(categoryRoot){
			@Override
			public void deleteIt() {
				if (getCategoryData() == null) {
					removeFromParent();
					removeFromTree();
					return;
				}
				presenter.deleteCategory(getCategoryData(), this);
			}

		};
		wItem.setData(0, categoryData);
		return wItem;
	}
	private void atachHandler(final CategoryWidget mainCategoryWidget,
			final TreeItem mailPanelRoot) {
		mainCategoryWidget.addItemAddedHandler(new ItemAddedHandler() {
			public void onItemAdded(ItemAddedEvent event) {
				CategoryEditItemWidget wItem = new CategoryEditItemWidget(mailPanelRoot){
					@Override
					public void deleteIt() {
						if (getCategoryItemData() == null) {
							removeFromParent();
							removeFromTree();
							return;
						}
						presenter.removeCategoryItem(getCategoryItemData().getId(),this);
					}
				};
				TreeItem treeItem =mailPanelRoot.addItem(wItem);
				wItem.setTreeItem(treeItem);
				wItem.addChangeHandler(new ChangeHandler() {
					public void onChange(ChangeEvent event) {
						presenter.save(mailPanelRoot);
					}
				});
			}
		});
		mainCategoryWidget.addItemEditedHandler(new ItemEditedHandler() {
			public void onItemEdited(ItemEditedEvent event) {
				presenter.save(mailPanelRoot);
			}
		});

	}

	private void attachToTree(final TreeItem mailPanelRoot,
			CategoryItemDataProxy categoryItem, int i, CategoryWidget mainCategoryWidget) {
		CategoryEditItemWidget wItem = new CategoryEditItemWidget(mailPanelRoot){
			@Override
			public void deleteIt() {
				if (getCategoryItemData() == null) {
					removeFromParent();
					removeFromTree();
					return;
				}
				presenter.removeCategoryItem(getCategoryItemData().getId(),this);
			}
		};
		TreeItem treeItem=mailPanelRoot.addItem(wItem);
		wItem.setTreeItem(treeItem);
		wItem.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				presenter.save(mailPanelRoot);
			}
		});
		wItem.setData(i, categoryItem);
		wItem.draw();			    

	}


	@UiHandler("categoryAddButton")
	void onCategoryAddButtonClick(ClickEvent event) {
		createAndAttachCategory(null);
	}
	@Override
	public void initCategoryList(List<CategoryDataProxy> categoryDataList) {
		this.categoryDataList = categoryDataList;

	}
	@Override
	public void showCatoryTree() {
		categoryTree.removeItems();
		categoryRoot=categoryTree.addItem("Kategorie");
		drawTree();

	}
	@Override
	public void showMessage(String message) {
		MessageDialogBox messageDialogBox = new MessageDialogBox(message);
		messageDialogBox.center();
		messageDialogBox.show();
	}

	@Override
	public boolean isAlreadyInit() {
		return alreadyInit;
	}

	@Override
	public void setAlreadyInit(boolean alreadyInit) {
		this.alreadyInit = alreadyInit;
	}
}
